package com.fast.utils.redis;

import cn.hutool.json.JSONUtil;
import com.fast.exception.RedisConnectionException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author ruan cai yuan
 * @version 1.0
 * @fileName com.fast.utils.redis.RedisCache
 * @description: Redis存储类
 * @since 2024/6/30 14:29
 */
@SuppressWarnings(value = {"unchecked", "rawtypes"})
@Component
public class RedisCache {
    @Resource
    public RedisTemplate<String, Object> redisTemplate;

    /**
     * 检查 Redis 连接是否正常
     */
    private void checkConnection() {
        try {
            Objects.requireNonNull(redisTemplate.getConnectionFactory()).getConnection();
        } catch (Exception e) {
            throw new RedisConnectionException("Cannot get Jedis connection");
        }
    }

    /**
     * 缓存基本的对象，Integer、String、实体类等
     *
     * @param key   缓存的键值
     * @param value 缓存的值
     */
    public <T> void setCacheObject(final String key, final T value) {
        checkConnection();
        String jsonStr = JSONUtil.toJsonStr(value);
        redisTemplate.opsForValue().set(key, jsonStr);
    }

    /**
     * 缓存基本的对象，Integer、String、实体类等
     *
     * @param key      缓存的键值
     * @param value    缓存的值
     * @param timeout  时间
     * @param timeUnit 时间颗粒度
     */
    public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) {
        checkConnection();
        String jsonStr = JSONUtil.toJsonStr(value);
        redisTemplate.opsForValue().set(key, jsonStr, timeout, timeUnit);
    }

    /**
     * 判断 key是否存在
     *
     * @param key 键
     * @return true 存在 false不存在
     */
    public Boolean hasKey(String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 获得缓存的基本对象。
     *
     * @param key 缓存键值
     * @return 缓存键值对应的数据
     */
    public <T> T getCacheObject(final String key, Class<T> clazz) {
        Object operation = redisTemplate.opsForValue().get(key);
        if (operation != null) {
            return JSONUtil.toBean(operation.toString(), clazz);
        }
        return null;
    }

    /**
     * 删除单个对象
     *
     * @param key
     */
    public void deleteObject(final String key) {
        redisTemplate.delete(key);
    }
}
